unit TibiaUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ComCtrls, Menus, OleCtrls, Math, TlHelp32,
  MemoryDeclaration, Addresses, Utils;

type
  TCreature = record
  ID,LVL,ML,Exp,MP,MPMax,X,Y,Z,Speed: Integer;
  Moving,Dir,Outfit,Head,Body,Legs,Feet,Addon,Light,Light_Color,HPBar,HPMax,Visible,Skull,Party,BL:Byte;
  Found: Boolean;
  Name:String;
end;
type
  TPos = record
  X,Y,Z,Tile,Stack: Integer;
end;
type
  TStatus = record
  Battle,Haste,Paralyze,MShield,Drunk,Energy,Fire,Poison:Boolean
end;
type
  TItem = record
  ID,X,Y,Z: Integer;
  Count, BP, Slot: Byte;
  Found: Boolean;
end;
type
  TButtonRefresh = class(TButton)
  procedure RefreshClientList(Sender:TObject);
end;
type
  TButtonChoose = class(TButton)
  procedure ChooseClient(Sender:TObject);
end;

var
  //Client Chooser Stuff
  ClientChooser :TForm;
  ClientList :TListBox;
  Choose :TButtonChoose;
  Refresh :TButtonRefresh;
  Client :Integer;


  procedure CreateClientChooser(const title :string);
  function ShowClientChooser(const CChooserTitle:string): Integer;

implementation

function ShowClientChooser(const CChooserTitle:string): Integer;
begin
try
  CreateClientChooser(CChooserTitle);
finally
  ClientChooser.ShowModal;
  Result:=Client;
end;
end;

procedure CreateClientChooser(const Title :string);
begin
ClientChooser := TForm.Create(Application);
ClientChooser.Height := 230;
ClientChooser.Width := 200;
ClientChooser.Caption := Title;
ClientChooser.BorderStyle := bsToolWindow;
ClientList := TlistBox.Create(ClientChooser);
ClientList.Parent := ClientChooser;
ClientList.Align := alTop;
ClientList.Height := ClientChooser.ClientHeight - 39;
Choose := TButtonChoose.Create(ClientChooser);
Choose.Parent := ClientChooser;
Choose.Height := 25;
Choose.Width := 75;
Choose.Top := ClientList.Height + 8;
Choose.Left := 8;
Choose.Caption := 'Choose';
Choose.OnClick := Choose.ChooseClient;
Refresh := TButtonRefresh.Create(ClientChooser);
Refresh.Parent := ClientChooser;
Refresh.Height := 25;
Refresh.Width := 75;
Refresh.Top := ClientList.Height + 8;
Refresh.Left := ClientChooser.ClientWidth - Refresh.Width - 8;
Refresh.Caption := 'Refresh List';
Refresh.OnClick := Refresh.RefreshClientList;
end;

{ TButtonRefresh }

procedure TButtonRefresh.RefreshClientList(Sender: TObject);
var Proc: TProcessEntry32;
Snap: HWND;
begin
ClientList.Clear;
Snap := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS,0);
Proc.dwSize := SizeOf(TProcessEntry32);
Process32First(Snap,Proc);
repeat
// foi colocado o copy por causa de um bug do Windows 2000 que trunca o nome do processo
if UpperCase(Copy(ExtractFileName(Proc.szExeFile),1,15)) = Copy(UpperCase('tibia.exe'),1,15) then
begin
if BLPosition(Proc.th32ProcessID) = -1 then
ClientList.Items.Add('['+inttostr(Proc.th32ProcessID)+'] Not Logged In')
else
ClientList.Items.Add('['+inttostr(Proc.th32ProcessID)+']'+ReadStr(Proc.th32ProcessID, Addresses.bl_Start + 4 + Addresses.bl_StepCreatures * BLPosition(Proc.th32ProcessID)));
end;
until (not Process32Next(Snap,Proc));
end;

{ TButtonChoose }

procedure TButtonChoose.ChooseClient(Sender: TObject);
var
A,B: String;
Proc: TProcessEntry32;
Snap: HWND;
ProcessID:Integer;
begin
A:=Split(ClientList.items[ClientList.ItemIndex], '[', 2);
B:=Split(A, ']', 1);
ProcessID:=strtoint(B);
Snap := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS,0);
Proc.dwSize := SizeOf(TProcessEntry32);
Process32First(Snap,Proc);
repeat
if Proc.th32ProcessID = ProcessID then
begin
Client := ProcessID;
ClientChooser.Close;
end;
until (not Process32Next(Snap,Proc));
end;

end.
